import java.awt.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class World extends Canvas implements Runnable {
	private static final long serialVersionUID = 1L;
	List<Guy> typen;
	Tile[][] tiles;
	Thread th=null;
	List<Level> allLevels;
	Level currentLevel;
	SazanaServer parent=null;
	int oldkey=0;
	
	public World(SazanaServer sazana) {
		parent=sazana;
		setPreferredSize(new Dimension(1024, 768));
		allLevels = new ArrayList<Level>();	
		typen=new ArrayList<Guy>();
		
		Level test = new TestLevel();
		test.saveLevel("test4.lvl");
		loadAllLevels();
		LoadLevel(allLevels.get(0));
	
		//loadWorld(); // Welt laden
		
		th = new Thread(this);
		th.start();
	}
	
	public Guy createGuy() {
		Guy typ = new Guy(this, (tiles.length - 1) * 32, (tiles[0].length - 1) * 32);
		typ.PositionX = 64;
		typ.PositionY = 128;
		typen.add(typ);
		return typ;
	}
	
	public void loadAllLevels(){
    	File dir = new File(new java.io.File("").getAbsolutePath());

    	
    	File[] allFiles = dir.listFiles();
    	for (File file : allFiles) {
				if (file.getName().endsWith(".lvl")){
		    		Level temp = new Level();
		    		String fileName=file.getName();
					temp.loadLevel(fileName);
					allLevels.add(temp);
			}
		}
    }


	public void LoadLevel(Level level){
		tiles = new Tile[level.breite][level.hoehe];
		
		for (int x = 0; x < tiles.length; x++) {
			for (int y = 0; y < tiles[x].length; y++) {
				Tile t = new Tile();
				tiles[x][y] = t;
			}
		}
		
		for (LevelObject levelObject : level.levelObjects) {
			for (int x = 0; x < levelObject.object.length; x++) {
				for (int y = 0; y < levelObject.object[x].length; y++) {
					Tile t = levelObject.object[x][y];
					tiles[x + levelObject.startPositionX][y + levelObject.startPositionY] = t;
				}
			}
		}
		currentLevel = level;
	}
	
	public Level findLeftLevel(){
		for(Level item: allLevels) {
	        if (item.levelID==currentLevel.leftlLevelID) {
	            return item;
	        }
		}
		return null;
	}
	
	public Level findTopLevel(){
		for(Level item: allLevels) {
	        if (item.levelID==currentLevel.toplLevelID) {
	            return item;
	        }
		}
		return null;
	}
	
	public Level findBottomLevel(){
		for(Level item: allLevels) {
	        if (item.levelID==currentLevel.bottomlLevelID) {
	            return item;
	        }
		}
		return null;
	}
		
		public Level findrightLevel(){
			for(Level item: allLevels) {
		        if (item.levelID==currentLevel.rightLevelID) {
		            return item;
		        }
			}
			return null;
		}
	
	public void loadWorld() {
        if ((new File("world.dat")).exists()) {
        	try {
        		FileInputStream fs = new FileInputStream("world.dat");
                ObjectInputStream is = new ObjectInputStream(fs);
                tiles=(Tile[][])is.readObject();
                is.close();
            }
            catch (Exception e) {
            }
        }
	}
	
	public void saveWorld() {
		try {
			ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("world.dat"));
			os.writeObject(tiles);
			os.flush();
			os.close();
        	System.out.println("Welt gespeichert!");
		}
        catch(IOException e) {
        	System.out.println("Es ist ein Fehler beim Speichern aufgetreten.");
        }        
	}
	
	public void run() {
		while (th != null) {
			for (int i=0; i<typen.size(); i++) {
				// Neue Position aller Spieler berechnen
				Guy typ=typen.get(i);
				typ.clock();
				if (typ.PositionX <= -5){
					LoadLevel(findLeftLevel());
					typ.PositionX = typ.MaxX;
				}
				if (typ.PositionX > typ.MaxX){
					LoadLevel(findrightLevel());
					typ.PositionX = 0;
				}
				if (typ.PositionY > typ.MaxY){
					LoadLevel(findBottomLevel());
					typ.PositionY = 0;
				}
				if (typ.PositionY < -5){
					LoadLevel(findTopLevel());
					typ.PositionY = typ.MaxY;
				}
				// Neue Position an alle Spieler senden
				parent.broadCast("move#"+i+"#"+typ.PositionX+"#"+typ.PositionY+"#"+typ.dir);
			}
			
			
			try {
				Thread.sleep(35);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
